package com.umeox.moto.watch.themes.widget;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.umeox.moto.watch.themes.R;
import com.umeox.moto.watch.themes.dialog.AlertDialog;

import java.util.Hashtable;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class ProgressDialog implements Runnable, DialogInterface.OnDismissListener {

    private static Hashtable<String, ProgressDialog> dialogMap;
    private static ScheduledThreadPoolExecutor schedulerExecutor;
    private static ScheduledFuture mFuture;

    private OnProgressDismissListener listener;

    private AlertDialog dialog;
    private ProgressView pvLoading;
    private TextView tvTip;

    private ProgressDialog(@NonNull Context context) {
        View view = LayoutInflater.from(context).inflate(R.layout.loading_dialog, null);
        dialog = new AlertDialog.Builder(context).setView(view).create();
        pvLoading = view.findViewById(R.id.pvCircular);
        tvTip = view.findViewById(R.id.tvTip);

        pvLoading.setVisibility(View.VISIBLE);
        tvTip.setVisibility(View.GONE);
    }

    private static synchronized Hashtable<String, ProgressDialog> getDialogMap() {
        if (dialogMap == null) {
            dialogMap = new Hashtable<>();
        }
        return dialogMap;
    }

    private static synchronized ScheduledThreadPoolExecutor getSchedulerExecutor() {
        if (schedulerExecutor == null) {
            schedulerExecutor = new ScheduledThreadPoolExecutor(1,
                    new ThreadFactory() {
                        private AtomicInteger count = new AtomicInteger(0);

                        @Override
                        public Thread newThread(@NonNull Runnable r) {
                            Thread thread = new Thread(r);
                            thread.setName("progress-dialog-scheduler-" + count.addAndGet(1));
                            return thread;
                        }
                    });
            //延时的schedule在shutdown后，不会继续执行没到时间的任务
            // 默认是true，会执行一次正在倒计时的任务再结束
            schedulerExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
            //延时的scheduleAtFixedRate/scheduleWithFixedDelay在shutdown后，不会继续执行没到时间的任务
            // 默认是true，会执行一次正在倒计时的任务再结束
            schedulerExecutor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
        }
        //取消当前任务
        if (mFuture != null && !mFuture.isCancelled()) {
            mFuture.cancel(true);
        }
        //获取未完成的任务队列
        BlockingQueue<Runnable> queues = schedulerExecutor.getQueue();
        if (queues != null && !queues.isEmpty()) {
            Runnable task = queues.poll();
            while (task != null) {
                schedulerExecutor.remove(task);
                task = queues.poll();
            }
        }
        return schedulerExecutor;
    }

    private static ProgressDialog createHud(Context ctx) {
        if (ctx == null) {
            return null;
        }
        ProgressDialog hud = getDialogMap().get(ctx.getClass().getName());
        if (hud == null) {
            hud = new ProgressDialog(ctx);
            getDialogMap().put(ctx.getClass().getName(), hud);
        }
        return hud;
    }

    public static void showProgress(Context ctx) {
        if (ctx == null) {
            return;
        }
        showProgress(ctx, false);
    }

    public static void showProgress(Context ctx, boolean cancelable) {
        if ((ctx instanceof Activity) && ((Activity) ctx).isFinishing()) {
            return;
        }
        ProgressDialog hud = createHud(ctx);
        if (hud != null) {
            hud.dialog.setCancelable(cancelable);
            hud.dialog.setCanceledOnTouchOutside(cancelable);
            hud.dialog.setOnDismissListener(hud);
            if (!hud.dialog.isShowing()) {
                hud.dialog.show();
                hud.pvLoading.start();
                hud.pvLoading.setVisibility(View.VISIBLE);
                hud.tvTip.setText("");
                hud.tvTip.setVisibility(View.GONE);
            }
        }
    }

    public static void dismissProgress(Context ctx) {
        ProgressDialog hud = createHud(ctx);
        if (hud != null) {
            if (mFuture != null
                    && !mFuture.isDone()) {
                mFuture.cancel(true);
            }
            if (hud.dialog.isShowing()) {
                hud.dialog.dismiss();
            }
        }
    }

    public static void dismissProgress(Context ctx, String message) {
        dismissProgress(ctx, message, 0, null);
    }

    public static void dismissProgress(Context ctx, String message, long delay) {
        dismissProgress(ctx, message, delay, null);
    }

    public static void dismissProgress(Context ctx, long delay) {
        dismissProgress(ctx, null, delay, null);
    }

    public static void dismissProgress(Context ctx, long delay, OnProgressDismissListener listener) {
        dismissProgress(ctx, null, delay, listener);
    }

    public static void dismissProgress(Context ctx, String message, OnProgressDismissListener listener) {
        dismissProgress(ctx, message, 0, listener);
    }

    public static void dismissProgress(Context ctx, String msg, long delay, OnProgressDismissListener listener) {
        ProgressDialog hud = createHud(ctx);
        if (hud != null) {
            if (mFuture != null
                    && !mFuture.isDone()) {
                mFuture.cancel(true);
            }
            if (delay <= 0 || delay > 30 * 1000) {
                //最长显示30秒，默认1秒
                delay = 1500;
            }
            if ((ctx instanceof Activity) && ((Activity) ctx).isFinishing()) {
                return;
            }
            if (!TextUtils.isEmpty(msg)) {
                hud.pvLoading.stop();
                hud.pvLoading.setVisibility(View.GONE);
                hud.tvTip.setText(msg);
                hud.tvTip.setVisibility(View.VISIBLE);
            } else {
                hud.pvLoading.start();
                hud.pvLoading.setVisibility(View.VISIBLE);
            }
            hud.listener = listener;

            mFuture = getSchedulerExecutor().schedule(hud, delay, TimeUnit.MILLISECONDS);
        }
    }

    @Override
    public void run() {
        if (dialog.isShowing()) {
            dialog.dismiss();
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        pvLoading.stop();
        pvLoading.setVisibility(View.GONE);
        tvTip.setText("");
        tvTip.setVisibility(View.GONE);
        if (listener != null) {
            listener.onDismiss(this);
            listener = null;
        }
    }

    public interface OnProgressDismissListener {
        void onDismiss(ProgressDialog dialog);
    }
}
